# -*- coding: utf-8 -*-
# Author: xiantingDeng
# File: element.py
# Time: 17:37

import time

import allure
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from common.utils.file_util import get_img_file_path


class WebTools():
    def __init__(self, driver, log):
        self.__driver = driver
        self.__log = log

    def get_element(self, locator, ignore_error=False):
        '''
        以不等待方式获取页面元素
        :param locator: 定位方式以字典传输
        :param ignore_error: 是否忽略异常，默认不忽略
        :return: 查找到的元素
        '''
        select_by = locator.get("selector")
        value = locator.get("selector_by")
        try:
            if select_by == "id":
                return self.__driver.find_element_by_id(value)
            elif select_by == "name":
                return self.__driver.find_element_by_name(value)
            elif select_by == "link_text":
                return self.__driver.find_element_by_link_text(value)
            elif select_by == "className":
                return self.__driver.find_element_by_class_name(value)
            elif select_by == "xpath":
                return self.__driver.find_element_by_xpath(value)
            elif select_by == "css":
                return self.__driver.find_element_by_css_selector(value)
            else:
                raise NameError("Please enter a valid type of targeting elements.")
        except Exception as e:
            if not ignore_error:
                self.__log.error(e)
                raise e
            else:
                return False

    def get_element_wait(self, locator, timeout=5, ignore_error=False):
        '''
        以显示方法获取页面元素
        :param locator: 定位方式，以字典方式传递
        :param timeout: 超时时间
        :param ignore_error: 是否忽略异常
        :return: 查找到的元素
        '''
        select_by = locator.get("selector")
        value = locator.get("selector_by")
        try:
            if select_by == "id":
                return WebDriverWait(self.__driver, timeout).until(
                    EC.visibility_of_all_elements_located((By.ID, value)))
            elif select_by == "name":
                return WebDriverWait(self.__driver, timeout).until(
                    EC.visibility_of_all_elements_located((By.NAME, value)))
            elif select_by == "link_text":
                return WebDriverWait(self.__driver, timeout).until(
                    (EC.visibility_of_all_elements_located((By.LINK_TEXT, value))))
            elif select_by == "className":
                return WebDriverWait(self.__driver, timeout).until(
                    EC.visibility_of_all_elements_located((By.CLASS_NAME, value)))
            elif select_by == "xpath":
                return WebDriverWait(self.__driver, timeout).until(
                    EC.visibility_of_all_elements_located((By.XPATH, value)))
            elif select_by == "css":
                return WebDriverWait(self.__driver, timeout).until(
                    EC.visibility_of_all_elements_located((By.CSS_SELECTOR, value)))
            else:
                raise NameError("Please enter a valid type of targeting elements.")
        except Exception as e:
            if not ignore_error:
                self.__log.error(e)
                raise e
            else:
                return False

    def get_elements_wait(self, locatrt, timeout=5, ignore_error=False):
        '''
        显示等待方式获取页面多个元素
        :param locatrt: 定位方式，以定位方式传递
        :param timeout: 超时时间
        :param ignore_error: 是否忽略异常
        :return: 返回查找到的元素
        '''
        selector_by = locatrt.get("selector")
        value = locatrt.get("selector_by")
        try:
            if selector_by == "id":
                return WebDriverWait(self.__driver, timeout).until(lambda x: x.find_element_by_id(value))
            elif selector_by == "name":
                return WebDriverWait(self.__driver, timeout).until(lambda x: x.find_element_by_name(value))
            elif selector_by == "link_text":
                return WebDriverWait(self.__driver, timeout).until(lambda x: x.find_element_by_link_text(value))
            elif selector_by == "className":
                return WebDriverWait(self.__driver, timeout).until(lambda x: x.find_element_by__class_name(value))
            elif selector_by == "xpath":
                return WebDriverWait(self.__driver, timeout).until(lambda x: x.find_element_by_xpath(value))
            elif selector_by == "css":
                return WebDriverWait(self.__driver, timeout).until(lambda x: x.find_element_by_css_selector(value))
            else:
                raise NameError("Please enter a valid type of targeting elements.")
        except Exception as e:
            if not ignore_error:
                self.__log.error(e)
                raise e
            else:
                return False

    def element_status(self, element, timeout=5, msg=None, ignore_error=False):
        '''
        元素状态检测，是否存在
        :param element: 待检测元素
        :param timeout: 超时时间
        :param msg: 元素描述
        :return:返回 TRUE or FALSE
        '''
        try:
            assert element.is_displayed() == True
            return True
        except Exception as e:
            return False

    def Jumpwepage(self, url, time_wait=3):
        '''
        打开网页地址
        :param url: url地址
        :param time_wait: 等待时间
        '''
        with allure.step("打开网页：{}".format(url)):
            try:
                self.__driver.get(url)
                self.__driver.maximize_window()
                self.__driver.implicitly_wait(10)
                if isinstance(time_wait, int):
                    time.sleep(time_wait)
                self.__log.debug("打开网页：{}".format(url))
            except:
                raise

    def forwawrd(self):
        '''
        浏览器前进操作
        :return:
        '''
        with allure.step("浏览器向前一步"):
            try:
                self.__driver.forward()
                self.__log.debug("浏览器向前一步")
            except:
                raise

    def back(self):
        '''
        浏览器后退操作
        :return:
        '''
        with allure.step("浏览器后退一步"):
            try:
                self.__driver.back()
                self.__log.debug("浏览器后退一步")
            except:
                raise

    def quit_rowser(self):
        '''
        关闭并停止浏览器服务
        :return:
        '''
        with allure.step("关闭并停止浏览器"):
            try:
                self.__driver.quit()
                self.__log.debug("关闭并停止浏览器")
            except:
                raise

    def click_element(self, element, msg):
        '''
        点击元素
        :param element: 待点击元素
        :param msg: 元素描述
        :return:
        '''
        with allure.step("{}：点击完成"):
            try:
                if self.element_status(element):
                    element.click()
                    self.__log.debug("{}:点击完成".format(msg))
                else:
                    self.__log.warning("当前界面没有找到-【{}】".format(msg))
            except Exception as e:
                self.__log.error("{}界面点击操作，出现异常，异常原因：{}".format(msg, e))

    def input_vlaue(self, element, values, msg):
        '''
        输入明文内容
        :param element: 待输入元素
        :param values: 待输入内容
        :param msg: 元素描述
        :return:
        '''
        with allure.step("{}：输入完成{}".format(msg, values)):
            try:
                if self.element_status(element):
                    element.send_keys()
                    self.__log.debug("{}:完成输入：{}".format(msg, values))
                else:
                    self.__log.warning("当前界面没有找到-【{}】".format(msg))
            except Exception as e:
                self.__log.error("{}界面输入操作，出现异常，异常原因：{}".format(msg, e))

    def element_clear(self, element, msg):
        '''
        清除输入框内容
        :param element: 待操作元素
        :param msg: 元素描述
        :return:
        '''
        with allure.step("{}：清除完成".format(msg)):
            try:
                if self.element_status(element):
                    element.clear()
                    self.__log.debug("{}：内容清除完成".format(msg))
                else:
                    self.__log.warning("当前界面没有找到-【{}】".format(msg))
            except Exception as e:
                self.__log.error("{}界面清除内容，出现异常，异常原因{}".format(msg, e))

    def get_element_text(self, element, msg):
        '''
        获取元素文本内容
        :param element: 待操作元素
        :param msg: 元素描述
        :return:
        '''
        text = None
        with allure.step("{}：获取到的文本内容为：{}".format(msg, text)):
            try:
                if self.element_status(element):
                    text = element.text
                    self.__log.debug("{}：获取到的文本内容为：{}".format(msg, text))
                    return text
                else:
                    self.__log.warning("当前界面没有找到-【{}】".format(msg))
            except Exception as e:
                self.__log.error("{}界面获取文本内容，出现异常，异常原因：{}".format(msg, e))

    def driver_screenshot(self, name):
        '''
        操作步骤截图，该截图会增加到allure测试报告的log日志中
        :param name: 图片名称
        :return: 返回截图路径
        '''
        img = get_img_file_path(name)
        with allure.step("正在进行截图操作：{}.png，存放路径为：{}".format(name, img)):
            self.__driver.save_screenshot(img)
            self.__log("截取屏幕成功，保存路径为：{}".format(img))
            with open(img, "rb") as f:
                file = f.read()
                allure.attach(file, name, allure.attachment_type.PNG)
            return img




if __name__ == '__main__':
    ids = {
        "selector": "id",
        "selector_by": "sus"
    }
    driver = webdriver.Chrome()
    from common.utils.log_util import logger

    el = WebTools(driver, logger())
    el.Jumpwepage("http://www.baidu.com")
    s = el.get_elements_wait(ids)
    print(el.element_status(s))
